更新のロスト lost update anomaly
r1[x=A]r2[x=A]w1[x=A +1]w2[x=A+1]c1c2
$ \left[ \begin{array}{cc} T_1 & T_2 \\ r_1[x=A] & \\ & r_2[x=A] \\ w_1[x = A + 1] & \\ & w_2[x = A + 1] \\ c_1 & c_2 \end{array} \right]
A=1だとすると結果x=1となるがトランザクションを別々に実行すればx=2であるはず
「値を読み込んで修正し書き込む」時に起きる
たとえば
wikiのページを更新する
ページごとにカウンタを作ってアクセスあるたびにインクリメントしていく
対応方法
アトミックな操作で行う
update c set v = v + 1 where k = 'key'
wikiのページを更新するとかには使えない
普通アトミックな操作というのは読み取りの際排他ロックをとり更新が適用されるまで他のトランザクションから読めないようにする
後述するMySQLの場合まさにupdateの際は暗黙的に排他ロックをとっている
明示的にロックをとる
---.icon
MySQLの場合
MVCCの場合lost updateを防げないのは教科書通り
ロッキングリードの場合は常に最新の値が読み取られる
つまりノンロッキングリードの場合とは読み取る値が異なる可能性がある
? 一貫性が損なわれているといってもいい